import yaml from "js-yaml";
import path from "path-browserify";

export interface BlogProperties {
  title?: string;
  keywords?: string[];
  [key: string]: any;
}

export interface BlogData {
  title: string;
  keywords: string[];
  text: string;
  lastModified: Date | null;
}

export default {
  blogDir: "./blogs",

  getBlog(
    blogPath: string,
    callback: (err: Error | null, data: BlogData) => void
  ) {
    let xhr = new XMLHttpRequest();
    xhr.open("get", blogPath);
    xhr.onreadystatechange = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        let lastModifiedHeader = xhr.getResponseHeader("last-modified");
        let lastModified = lastModifiedHeader
          ? new Date(lastModifiedHeader)
          : null;

        let rawText = xhr.responseText.replaceAll("\r\n", "\n");
        let match = rawText.match(/^(---\n(.+\n)?---)?(.*)$/s);

        let yamlText = match?.[2];
        let properties = yamlText
          ? (yaml.load(yamlText) as BlogProperties)
          : {};

        let text = match?.[3] || "";

        let title =
          properties?.title ||
          text.match(/#\s+(.+)\n/)?.[1] ||
          path.basename(blogPath, ".md");
        let keywords = properties.keywords || [];

        callback(null, { title, keywords, text, lastModified });
      } else {
        callback(new Error(`${xhr.status}: ${xhr.statusText}`), {} as BlogData);
      }
    };
    xhr.send();
  },
  getLinks(
    contentsPath: string,
    callback: (err: Error | null, contents: string[]) => void
  ) {
    let xhr = new XMLHttpRequest();
    xhr.open("get", contentsPath);
    xhr.onreadystatechange = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        let rawText = xhr.responseText.replaceAll("\r\n", "\n");
        let contents: string[] = [];

        let patternLink = /(?<!!)\[(.*?)\]\((.*?)\)/g;
        let match;
        while ((match = patternLink.exec(rawText))) {
          contents.push(path.join(path.dirname(contentsPath), match?.[2]));
        }

        callback(null, contents);
      } else {
        callback(new Error(`${xhr.status}: ${xhr.statusText}`), []);
      }
    };
    xhr.send();
  },
};
